#pragma once

#include <string>
#include <vector>
#include <memory>

#ifdef _WIN32
//#include <winsock.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#endif // !M_PI

#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>

using namespace pcl::visualization;

#ifdef _WIN32
#ifdef ISCLIBLIDAR_EXPORTS
#define ISCLIBLIDAR_API __declspec(dllexport)
#elif defined(DEMO_BUILD)
#define ISCLIBLIDAR_API  // 在demo模式下不使用导入/导出
#else
#define ISCLIBLIDAR_API __declspec(dllimport)
#endif
#else
#define ISCLIBLIDAR_API
#endif

#include <cmath>

/// @brief 激光雷达 输入源 类型
enum class ISCLIBLIDAR_API LidarInputSourceType
{
    ONLINE_LIDAR = 1,
    PCAP_FILE,
    RAW_PACKET,
    PCD_FILE
};

/// @brief 激光雷达 制造商 类型
enum class ISCLIBLIDAR_API LidarManufacturerType
{
    // RoboSense
    RS_16 = 0x01,
    RS_32,
    RS_BP,
    RS_HELIOS,
    RS_128,
    RS_80,
    RS_M1,

    // Hesai
    AT_128,
};

/// @brief 激光雷达点云 解析类型
enum class ISCLIBLIDAR_API LidarDecodeType
{
    RAW,         // 原始数据类型
    DENSE,       // 去除NAN值
    FILTERED,    // 去除离群点
    DOWNSAMPLED, // 下采样
};

/// @brief 激光雷达点云回调数据
template <typename PointT>
struct ISCLIBLIDAR_API PointCloudData
{
    typedef typename pcl::PointCloud<PointT>::Ptr PointCloudPtr;
    PointCloudPtr cloud_ptr;
    double timestamp{0};
    uint32_t sequence{0};
    std::string frame_id{""};
    int lidar_id{0};
};

struct ISCLIBLIDAR_API TransformParam
{
    float x = 0.0f;     ///< unit, m
    float y = 0.0f;     ///< unit, m
    float z = 0.0f;     ///< unit, m
    float roll = 0.0f;  ///< unit, radian
    float pitch = 0.0f; ///< unit, radian
    float yaw = 0.0f;   ///< unit, radian
};
using PointCloudDataCallback = std::function<void(PointCloudData<pcl::PointXYZI> &)>;